package unei;

import com.sun.javafx.tk.Toolkit;

import java.util.concurrent.*;

/**
 * Created by sun on 2015/6/27.
 */
public class DelayQueueTest {
    public static void main(String[] args){
//        ThreadPoolExecutor executor=new ThreadPoolExecutor(10,100,100, TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(1000));
//        System.out.println(TimeUnit.NANOSECONDS.toMicros(1000));
        final DelayQueue<TaskDelayed> delayQueue=new DelayQueue();
        TaskDelayed taskDelayed1=new TaskDelayed(1,5);
        TaskDelayed taskDelayed2=new TaskDelayed(2,5);
        TaskDelayed taskDelayed3=new TaskDelayed(3,5);
        delayQueue.add(taskDelayed1);
        delayQueue.add(taskDelayed2);
        delayQueue.add(taskDelayed3);
        new Thread(){
            public void run(){
                for(int i=0;i<3;i++){
                    try {
                        System.out.println(delayQueue.take().getId());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();

    }

    static class TaskDelayed implements Delayed{
        /** Base of nanosecond timings, to avoid wrapping */
        private static final long NANO_ORIGIN = System.nanoTime();

        /**
         * Returns nanosecond time offset by origin
         */
        final static long now() {
            return System.nanoTime() - NANO_ORIGIN;
        }

        private Object id;
        private long timestamp;
        private long delayed; //default microsecond

        public TaskDelayed(Object id,long delayed){
            this.id=id;
            this.timestamp=now();
            this.delayed=TimeUnit.NANOSECONDS.convert(delayed,TimeUnit.SECONDS);
        }

        public long getDelay(TimeUnit unit) {
//            if(unit.compareTo(TimeUnit.NANOSECONDS)==0){
//                long a=unit.toNanos(delayed);
//                System.out.println(a);
//                return unit.toNanos(delayed);
//            }
            long diff=timestamp+delayed-now();

            return diff;
        }

        public int compareTo(Delayed o) {
            if(o==this)return 0;
            if(o instanceof TaskDelayed){
                TaskDelayed other=(TaskDelayed)o;
                long diff=timestamp-other.getTimestamp();
                if(diff<0)return -1;
                else if(diff>0)return 1;
                else return 0;
            }
            long d = (getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS));
            return (d == 0) ? 0 : ((d < 0) ? -1 : 1);
        }

        public Object getId() {
            return id;
        }

        public long getDelayed() {
            return delayed;
        }

        public long getTimestamp() {
            return timestamp;
        }
    }
}
